package view;

import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Image;

import view.screen.ConfigurationMenuScreen;
import view.screen.ConnectionScreen;
import view.screen.ContactsScreen;
import view.screen.ContactsSourceScreen;
import view.screen.ImageSelectionScreen;
import view.screen.InformationScreen;
import view.screen.MessageScreen;
import view.screen.MessengerScreen;
import view.screen.WelcomeScreen;
import base.ScreenActionListener;
import data.ConversationRecorder;
import data.ImageConverter;
import exceptions.InitializedException;
import exceptions.InvalidParametersException;
import exceptions.InvalidScreenException;
import exceptions.NotInitializedException;

public class View {

	// Screen codes
	public static final byte WELCOME_SCREEN = 0x0;
	public static final byte CONFIG_SCREEN = 0x1;
	public static final byte CONNECTION_SCREEN = 0x2;
	public static final byte IMAGE_SCREEN = 0x3;
	public static final byte CONTACTS_SOURCE_SCREEN = 0x4;
	public static final byte INFO_SCREEN = 0x5;
	public static final byte CONTACTS_SEARCH_SCREEN	= 0x6;
	public static final byte CONTACTS_DB_SCREEN	= 0x7;
	public static final byte MESSENGER_SCREEN = 0x8;
	public static final byte MESSAGE_SCREEN = 0x9;

	private Display display;

	private ConversationRecorder conversation;

	private Displayable[] cache;

	public void init(Display display) throws InitializedException {
		if(this.display != null)
			throw new InitializedException();
		this.display = display;
		conversation = new ConversationRecorder(7);
		cache = new Displayable[10];
	}

	public boolean selectScreen(byte screen, ScreenActionListener control) throws Exception {
		if(display == null)
			throw new NotInitializedException();
		boolean screenOn = false;
		switch (screen) {
		case WELCOME_SCREEN:
			cache[WELCOME_SCREEN] = new WelcomeScreen(control);
			display.setCurrent(cache[WELCOME_SCREEN]);
			screenOn = true;
			break;
		case CONTACTS_SOURCE_SCREEN:
			cache[CONTACTS_SOURCE_SCREEN] = new ContactsSourceScreen(control);
			display.setCurrent(cache[CONTACTS_SOURCE_SCREEN]);
			screenOn = true;
			break;
		case MESSAGE_SCREEN:
			display.setCurrent(new MessageScreen(control));
			screenOn = true;
			break;
		}
		if(!screenOn)
			throw new InvalidScreenException();

		return true;
	}

	public boolean selectScreen(byte screen, ScreenActionListener control,
			String[] list) throws Exception {
		if(display == null)
			throw new NotInitializedException();
		if(list.length == 0)
			throw new InvalidParametersException();
		boolean screenOn = false;
		switch (screen) {
		case CONFIG_SCREEN:
			cache[CONFIG_SCREEN] = new ConfigurationMenuScreen(control, list[0]);
			display.setCurrent(cache[CONFIG_SCREEN]);
			screenOn = true;
			break;
		case CONNECTION_SCREEN:
			cache[CONNECTION_SCREEN] = new ConnectionScreen(control, list);
			display.setCurrent(cache[CONNECTION_SCREEN]);
			screenOn = true;
			break;
		case CONTACTS_SEARCH_SCREEN:
			cache[CONTACTS_SEARCH_SCREEN] = new ContactsScreen(control, list, false);
			display.setCurrent(cache[CONTACTS_SEARCH_SCREEN]);
			screenOn = true;
			break;
		case CONTACTS_DB_SCREEN:
			cache[CONTACTS_DB_SCREEN] = new ContactsScreen(control, list, true);
			display.setCurrent(cache[CONTACTS_DB_SCREEN]);
			screenOn = true;
			break;
		case INFO_SCREEN:
			cache[INFO_SCREEN] = new InformationScreen(list[0]);
			display.setCurrent(cache[INFO_SCREEN]);
			screenOn = true;
			break;
		}
		if(!screenOn)
			throw new InvalidScreenException();

		return true;
	}

	public boolean selectScreen(byte screen, ScreenActionListener control,
			String[] list, Image[] image) throws Exception{
		if(display == null)
			throw new NotInitializedException();
		if(list.length != image.length || image.length == 0)
			throw new InvalidParametersException();
		boolean screenOn = false;
		switch (screen) {
		case IMAGE_SCREEN:
			cache[IMAGE_SCREEN] = new ImageSelectionScreen(control, list, image);
			display.setCurrent(cache[IMAGE_SCREEN]);
			screenOn = true;
			break;
		case MESSENGER_SCREEN:
			conversation.reset();
			cache[MESSENGER_SCREEN] = new MessengerScreen(control, list[0], ImageConverter.createThumbnail(image[0]), conversation);
			display.setCurrent(cache[MESSENGER_SCREEN]);
			screenOn = true;
			break;
		}
		if(!screenOn)
			throw new InvalidScreenException();

		return true;
	}

	public boolean selectScreen(byte screen) throws Exception{
		if(cache[screen] != null){
			display.setCurrent(cache[screen]);
			switch(screen){
			case MESSENGER_SCREEN:
				((MessengerScreen)cache[MESSENGER_SCREEN]).repaint();
				break;
			case WELCOME_SCREEN:
				((WelcomeScreen)cache[WELCOME_SCREEN]).repaint();
				break;
			case INFO_SCREEN:
				((InformationScreen)cache[INFO_SCREEN]).repaint();
				break;
			}
		}
		else
			throw new NotInitializedException();
		return true;
	}


	public boolean showMsg(String user, String msg) {
		conversation.addMessage(user, msg);
		((MessengerScreen)cache[MESSENGER_SCREEN]).repaint();
		return true;
	}

	public boolean isCached(byte screen){
		return cache[screen]!=null;
	}

	public boolean showError(String message, byte nextScreen) {
		Displayable d = null;
		if(nextScreen == -1)
			d = display.getCurrent();
		else
			switch (nextScreen) {
			case WELCOME_SCREEN:
				d = cache[WELCOME_SCREEN];
				break;
			case CONTACTS_SOURCE_SCREEN:
				d = cache[CONTACTS_SOURCE_SCREEN];
				break;
			}
		Alert a = new Alert(null);
		a.setString(message);
		a.setTimeout(2000);

		display.setCurrent(a, d);
		return false;
	}

}
